<template>
  <div class="main">
    <div class="content">
      <div class="search-box">
        <img src="~@/assets/img/back.png" alt="返回" @click="$router.go(-1)" />
        <div class="title">知识图谱智能查询</div>
        <div class="search-area">
          <div class="input-box">
            <el-select v-model="searchData.projectId" placeholder="请选择图谱">
              <el-option
                v-for="item in graphList"
                :key="item.projectId"
                :label="item.projectName"
                :value="item.projectId"
              ></el-option>
            </el-select>
            <div class="vertical-line"></div>
            <el-input
              v-model="searchData.searchKey"
              placeholder="请输入节点名称"
              clearable
              @change="useTranslate"
            />
            <img
              src="@/assets/img/translation.png"
              alt="实体链接"
              width="24px"
              height="24px"
              class="trans-img"
              @click="openTrans"
            />
          </div>
          <el-button @click="reSearch('normal')" icon="el-icon-search"
            >查询</el-button
          >
          <el-link :underline="false" @click="openAdvanceSearch"
            >高级检索</el-link
          >
          <!-- 翻译区域 -->
          <transition name="el-zoom-in-top">
            <div v-if="showTransBox" class="translation-box">
              <div class="change-box">
                <div>
                  <span>实体链接</span>
                  <el-switch
                    v-model="searchData.bilingual"
                    active-color="#00AAFF"
                    inactive-color="#133f77"
                  >
                  </el-switch>
                </div>
              </div>
              <!-- 翻译结果区域 -->
              <div
                v-loading="loading"
                element-loading-background="rgba(1, 43, 80, 0.5) "
                class="trans-result"
              >
                {{ searchData.translateKey }}
              </div>
              <img
                src="~@/assets/img/close.png"
                alt="关闭"
                @click="showTransBox = false"
              />
            </div>
          </transition>
        </div>
      </div>
      <div class="box">
        <div class="left-box">
          <div class="switch-box">
            <div
              v-for="(item, index) in typeOptions"
              :key="index"
              :class="[
                typeSelect === item.ontologyId
                  ? 'switch-item-selected'
                  : 'switch-item',
              ]"
              @click="changeTag(item.ontologyId)"
            >
              {{ item.ontologyName }}
            </div>
          </div>
          <div class="card-box-1" ref="scrollDiv">
            <div
              v-for="(item, index) in list"
              :key="index"
              @click="getGraphAnalysis(item)"
            >
              <Card ref="card" :item="item" :searchKey="searchData.searchKey" />
              <div v-if="index + 1 !== list.length" class="line"></div>
            </div>

            <div v-for="(item, index) in fileList" :key="index">
              <CardFile
                ref="cardFile"
                :item="item"
                :searchKey="searchData.searchKey"
              />
            </div>
            <el-pagination
              :current-page.sync="pagination.pageNum"
              :page-size="pagination.pageSize"
              :hide-on-single-page="true"
              layout="prev, pager, next"
              :total="pagination.total"
              @current-change="search"
            >
            </el-pagination>
          </div>
        </div>
        <div class="right-box">
          <div class="graph-box">
            <div class="title">
              <div
                class="m-l-20"
                :class="[activeName === '1' ? 'right-active' : '']"
                @click="activeName = '1'"
              >
                图谱分析
              </div>
              <div
                class="m-l-40"
                :class="[activeName === '2' ? 'right-active' : '']"
                @click="activeName = '2'"
              >
                关系列表
              </div>
              <div class="m-l-40" @click="goViewManagement">关联分析</div>
            </div>
            <div class="graph-content">
              <Graph
                v-show="activeName === '1'"
                class="intelligence-map"
                :dataset="graphData"
              ></Graph>
              <div v-show="activeName === '2'" class="relationship">
                <el-table :data="tableData" border>
                  <el-table-column
                    label="头实体"
                    prop="headBody"
                    align="center"
                  ></el-table-column>
                  <el-table-column
                    label="关系"
                    prop="relationship"
                    align="center"
                  ></el-table-column>
                  <el-table-column
                    label="尾实体"
                    prop="caudalBody"
                    align="center"
                  ></el-table-column>
                </el-table>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
    <AdvancedSearch
      ref="advancedSearch"
      position="result"
      @reSearch="reSearch"
      :graphList="graphList"
    />
  </div>
</template>

<script>
import { mapMutations } from 'vuex';
import Card from './common/card.vue';
import CardFile from './common/cardFile.vue';
import Graph from './common/knowledgeMap.vue';
import AdvancedSearch from './common/advancedSearch.vue';
// import {
//   getGraphList,
// } from "@/api/search";
import { debounce } from '@/plugins/utils';
export default {
  components: { Card, CardFile, Graph, AdvancedSearch },
  data() {
    return {
      searchData: {
        projectId: '',
        bilingual: false,
        searchKey: '',
        translateKey: '',
        searchPropList: [
          {
            type: 0,
            condition: 'AND',
            entityName: '',
            headEntityName: '',
            tailEntityName: '',
            relationName: '',
            propId: '',
            propValue: '',
          },
        ],
      },
      showTransBox: false, // 显示翻译框
      typeSelect: '', // 选择的类别
      typeOptions: [], // 类别列表
      list: [], // 卡片列表
      fileList: [], // 卡片文件列表
      graphData: {}, // 图谱数据
      activeName: '1',
      tableData: [], // 关系列表数据
      loading: false, // 翻译时的loading
      graphList: [],
      pagination: {
        pageNum: 1,
        pageSize: 5,
        total: 0,
      },
    };
  },
  created() {
    this.initSearchData();
    this.getTypeList();
    this.search();
  },
  methods: {
    ...mapMutations(['SET_SEARCHDATA']),
    // 初始化查询数据
    initSearchData() {
      const searchData = this.$store.state.search.searchData;
      if (searchData) {
        this.searchData = { ...searchData };
      } else {
        this.searchData = {
          projectId: '',
          bilingual: false,
          searchKey: '',
          translateKey: '',
          searchPropList: [
            {
              type: 0,
              condition: 'AND',
              entityName: '',
              headEntityName: '',
              tailEntityName: '',
              relationName: '',
              propId: '',
              propValue: '',
            },
          ],
        };
      }
      this.getGraph();
    },
    // 获取图谱列表
    getGraph() {
      const params = {
        pageNum: 1,
        pageSize: 50,
      };
      this.$axios
        .post(this.$api.search.searchApi.getGraphList, params)
        .then((res) => {
          const { data, code } = res.data;
          if (code == 200) {
            this.graphList = data.list;
            console.log(
              '%c [  this.graphList ]-267',
              'font-size:13px; background:pink; color:#bf2c9f;',
              this.graphList
            );
            if (!this.searchData.projectId) {
              this.$set(
                this.searchData,
                'projectId',
                this.graphList[0]?.projectId
              );
            }
          }
        });
    },
    // 获得类别列表
    getTypeList() {
      this.typeOptions = [
        {
          ontologyName: '综合',
          ontologyId: '',
        },
      ];
      if (this.searchData?.type === 'normal') {
        if (this.searchData?.searchKey?.length === 0) {
          return;
        }
        const params = {
          searchKey: this.searchData.searchKey,
          translateKey: this.searchData.translateKey,
          projectId: this.searchData.projectId,
        };
        this.$axios
          .post(this.$api.search.searchApi.getSearchType, params)
          .then((res) => {
            const { data, code } = res.data;
            if (code == 200) {
              data.typeList?.forEach((item) => {
                this.typeOptions.push({
                  ontologyName: item.ontologyName,
                  ontologyId: item.ontologyId,
                });
              });
            }
          });
      } else if (this.searchData?.type === 'advanced') {
        const params = {
          projectId: this.searchData.projectId,
          searchPropList: this.searchData.searchPropList,
        };
        this.$axios
          .post(this.$api.search.searchApi.advancedSearchType, params)
          .then((res) => {
            const { data, code } = res.data;
            if (code == 200) {
              data.typeList?.forEach((item) => {
                this.typeOptions.push({
                  ontologyName: item.ontologyName,
                  ontologyId: item.ontologyId,
                });
              });
            }
          });
      }
    },
    // 默认调用检索
    search() {
      this.$nextTick(() => {
        let scrollElem = this.$refs.scrollDiv;
        scrollElem.scrollTo({ top: 0 });
      });
      if (this.searchData?.type === 'normal') {
        if (this.searchData?.searchKey?.length === 0) {
          return;
        }
        const params = {
          searchKey: this.searchData.searchKey,
          projectId: this.searchData.projectId,
          ontologyId: this.typeSelect,
          pageNum: this.pagination.pageNum,
          pageSize: this.pagination.pageSize,
        };
        if (this.searchData?.bilingual) {
          params.translateKey = this.searchData.translateKey;
        }
        this.$axios
          .post(this.$api.search.searchApi.smartSearch, params)
          .then((res) => {
            const { data, code } = res.data;
            if (code == 200) {
              this.fileList = data?.fileList;
              this.fileList?.forEach((item) => {
                item.type = item.fileUrl.split('.').pop();
              });
              console.log(999, this.fileList);
              this.list = data?.list;
              console.log(
                '%c [ this.list ]-358',
                'font-size:13px; background:pink; color:#bf2c9f;',
                this.list
              );
              this.list?.forEach((item) => {
                item.profile = this.getGraphName(this.searchData.projectId);
              });
              this.pagination.total = data?.total;
              if (this.list.length > 0) {
                this.getGraphAnalysis(this.list[0]);
              }
            }
          })
          .finally(() => {
            this.$refs.card?.forEach((item) => {
              item.setData(this.searchData.searchKey);
            });
            this.$refs.cardFile?.forEach((item) => {
              item.setData(this.searchData.searchKey);
            });
          });
      } else if (this.searchData?.type === 'advanced') {
        const params = {
          currentPage: this.pagination.pageNum,
          pageSize: this.pagination.pageSize,
          projectId: this.searchData.projectId,
          ontologyId: this.typeSelect,
          searchPropList: this.searchData.searchPropList,
        };
        this.$axios
          .post(this.$api.search.searchApi.advancedSearch, params)
          .then((res) => {
            const { data, code } = res.data;
            if (code == 200) {
              this.list = data?.list;
              this.list?.forEach((item) => {
                item.profile = this.getGraphName(this.searchData.projectId);
              });
              this.pagination.total = data?.total;
              if (this.list?.length > 0) {
                this.getGraphAnalysis(this.list[0]);
              }
            }
          })
          .finally(() => {
            this.$refs.card?.forEach((item) => {
              item.setData('');
            });
            this.$refs.card?.forEach((item) => {
              item.setData('');
            });
          });
      }
    },
    // 显示翻译页面
    openTrans() {
      if (this.showTransBox) {
        return (this.showTransBox = false);
      }
      this.showTransBox = true;
      this.useTranslate();
    },
    // 调用翻译
    useTranslate: debounce(function () {
      if (!this.showTransBox || this.searchData?.searchKey?.length === 0) {
        return;
      }
      this.loading = true;
      // const params = {
      //   text: this.searchData.searchKey,
      // };
      this.$axios
        .get(
          `${this.$api.search.searchApi.translate}?text=${this.searchData.searchKey}`
        )
        .then((res) => {
          let { data, code } = res.data;
          if (code == 200) {
            this.searchData.translateKey = data;
          }
        })
        .finally(() => {
          this.loading = false;
        });
    }, 500),
    // 高级检索
    openAdvanceSearch() {
      this.SET_SEARCHDATA({
        ...this.searchData,
        type: 'advanced',
      });
      this.$refs.advancedSearch.show();
    },
    // 查看图谱名称
    getGraphName(id) {
      return this.graphList.find((item) => item.projectId === id)?.projectName;
    },
    // 切换类别
    changeTag(ontologyId) {
      this.typeSelect = ontologyId;
      this.pagination.pageNum = 1;
      this.search();
    },
    // 再次重新检索
    reSearch(type) {
      this.pagination.pageNum = 1;
      this.typeSelect = '';
      this.showTransBox = false;
      if (type === 'normal') {
        this.searchData.type = 'normal';
      } else {
        this.initSearchData();
        this.searchData.type = 'advanced';
        this.searchData.searchKey = '';
      }
      this.getTypeList();
      this.search();
    },
    // 获取图谱分析数据
    getGraphAnalysis(item) {
      const params = {
        entityId: item.entityId,
      };
      this.$axios
        .post(this.$api.search.searchApi.graphAnalysis, null, {
          params,
        })
        .then((res) => {
          const { data } = res.data;
          const { entityRelations, entityNodes } = data;
          if (entityNodes.length === 0 || entityRelations.length === 0) {
            this.graphData = {
              nodes: [],
              edges: [],
            };
            this.tableData = [];
            return;
          }
          const nodes =
            entityNodes.length > 0 &&
            entityNodes.map((item) => {
              item.id = String(item.id);
              return item;
            });
          if (entityRelations.length === 0) {
            return;
          }
          const edges =
            entityRelations.length > 0 &&
            entityRelations.map((item) => {
              item.id = String(item.id);
              return item;
            });
          this.tableData = entityRelations.map((item) => {
            return {
              ...item,
              relationship: item.label,
              headBody: this.getEntityName(nodes, item.source),
              caudalBody: this.getEntityName(nodes, item.target),
            };
          });
          this.graphData = { nodes, edges };
        });
    },
    // 根据id获取列表中某项的实体名称
    getEntityName(nodes, id) {
      return nodes.find((item) => item.id === id)?.name;
    },
    goViewManagement() {
      this.$router.push({
        path: '/manage/viewManagement',
        query: {
          projectId: this.searchData.projectId,
        },
      });
    },
  },
};
</script>

<style lang="scss" scoped>
.main {
  height: 100%;
  width: 100%;
  background: url('~@/assets/img/search_bg.png') no-repeat;
  background-size: 100% 100%;
  .content {
    width: 100%;
    height: 100%;
    padding: 40px;
    box-sizing: border-box;
    .search-box {
      height: 64px;
      display: flex;
      justify-content: flex-start;
      align-items: center;
      margin-bottom: 20px;
      .title {
        width: 99px;
        font-family: PingFangSC, PingFang SC;
        font-weight: 500;
        font-size: 24px;
        color: #ffffff;
        background: linear-gradient(270deg, #74bbff 0%, #ffffff 100%);
        background-clip: text;
        -webkit-text-fill-color: transparent;
        margin-right: 24px;
      }
      img {
        cursor: pointer;
        margin-right: 100px;
      }
      .search-area {
        display: flex;
        position: relative;
        width: auto;
        height: 100%;
        .input-box {
          display: flex;
          align-items: center;
          width: calc(80% - 16px);
          height: 100%;
          box-shadow: inset 0px 0px 3px 0px #0180db;
          border: 1px solid #043661;
          background: rgba(3, 23, 46, 0.4);
          border-radius: 4px;
          margin-right: 16px;
          .el-select {
            ::v-deep .el-input__inner {
              height: 64px;
              font-size: 20px;
              color: #00aaff;
              background: transparent;
              border: none;
              border-radius: 0;
            }
          }
          .el-input {
            height: 64px;
            ::v-deep .el-input__inner {
              height: 100%;
              line-height: 100%;
              font-size: 20px;
              color: #ffffff;
              background: transparent;
              border: none;
              border-radius: 0;
            }
            ::v-deep .el-input__inner::-webkit-input-placeholder {
              color: darken(#ffffff, 30%);
            }
          }
          .trans-img {
            margin: 0 20px;
            cursor: pointer;
          }
          .vertical-line {
            width: 1px;
            height: 24px;
            border: 1px solid #0e436c;
          }
        }

        .el-button {
          height: auto;
          width: auto;
          border-radius: 4px;
          background: linear-gradient(
            to top,
            rgba(27, 188, 255, 0.89) 0%,
            rgba(7, 31, 63, 0) 100%
          );
          border-color: #0197ec;
          color: #ffffff;
          font-size: 20px;
        }
        .el-link {
          font-size: 20px;
          line-height: 28px;
          font-weight: 500;
          color: #00aaff;
          width: 100px;
          margin-left: 32px;
          ::v-deep .el-link--inner {
            color: #00aaff;
            &:hover {
              color: lighten(#00aaff, 30%);
            }
          }
        }
        .translation-box {
          position: absolute;
          width: calc(80% + 50px);
          height: 240px;
          padding: 20px;
          top: 74px;
          left: 0;
          border-radius: 4px;
          background: #012b50;
          border: 1px solid;
          z-index: 9999;
          border-image: linear-gradient(
              315deg,
              rgba(72, 168, 255, 1),
              rgba(9, 48, 92, 1),
              rgba(72, 168, 255, 1)
            )
            1 1;
          .change-box {
            display: flex;
            justify-content: flex-end;
            align-items: center;
            font-size: 20px;
            color: #6599ca;
            margin-bottom: 20px;
            .el-switch {
              margin-left: 8px;
            }
          }
          .trans-result {
            color: #ffffff;
            font-size: 20px;
          }
          img {
            position: absolute;
            bottom: -32px;
            cursor: pointer;
            left: calc(50% - 24px);
          }
        }
      }
    }
    .box {
      display: flex;
      padding: 0 5% 0 15%;
      height: calc(100% - 64px);
      .left-box {
        width: 50%;
        margin-right: 10px;
        height: 100%;
        .switch-box {
          position: relative;
          display: flex;
          height: 36px;
          margin-bottom: 20px;
          padding: 0 20px;
          overflow-y: scroll;
          .switch-item {
            height: 100%;
            font-size: 20px;
            font-style: oblique;
            text-align: left;
            color: #6599ca;
            cursor: pointer;
            position: relative;
            margin-right: 32px;
            white-space: nowrap;
          }
          .switch-item-selected {
            height: 100%;
            font-size: 20px;
            font-style: oblique;
            text-align: left;
            color: #ffffff;
            cursor: pointer;
            position: relative;
            margin-right: 32px;
            white-space: nowrap;
          }
          .switch-item-selected::after {
            content: '';
            position: absolute;
            bottom: 0;
            height: 50%; /* 这将覆盖div的上半部分 */
            width: 78px;
            left: 50%; /* 移动到水平中点 */
            transform: translate(
              -50%,
              0
            ); /* 根据自身大小进行偏移，实现完全居中 */
            background: url('~@/assets/img/selected.png');
            background-size: contain;
            background-position: center;
            background-repeat: no-repeat;
          }
        }
        .switch-box::before {
          content: '';
          position: absolute;
          left: 0;
          right: 0;
          bottom: 0;
          height: 50%; /* 这将覆盖div的上半部分 */
          background: linear-gradient(
            270deg,
            rgba(31, 96, 155, 0) 0%,
            rgba(31, 96, 155, 0.4) 51%,
            rgba(31, 96, 155, 0) 100%
          );
        }
        .card-box-1 {
          height: calc(100% - 190px);
          overflow: scroll;
          cursor: pointer;
          .el-pagination {
            margin-top: 16px;
            background-color: transparent;
            display: flex;
            justify-content: center;
          }
          .line {
            height: 1px;
            border: 1px solid #17395b;
            margin: 24px 0;
          }
        }
      }
      .right-box {
        width: 50%;
        margin-left: 10px;
        .graph-box {
          width: 100%;
          border: 1px solid #204467;
          border-radius: 4px;
          overflow: hidden;
          .title {
            color: #6599ca;
            font-size: 20px;
            display: flex;
            height: 54px;
            justify-content: flex-start;
            align-items: center;
            background: url('~@/assets/img/graph-title-bg.png');
            background-size: cover;
            background-position: center;
            background-repeat: no-repeat;
            font-style: oblique;
            cursor: pointer;
            .right-active {
              color: #ffffff;
              text-shadow: 0px 2px 4px #0485da;
            }
          }
          .graph-content {
            width: 100%;
            height: 550px;
            background-color: transparent;
            .relationship {
              width: 100%;
              padding: 16px;
            }
          }
        }
      }
    }
  }
}
::-webkit-scrollbar {
  display: none;
}
::v-deep {
  .el-table td.el-table__cell {
    border-bottom: 1px solid #1d4d80;
    background: rgba(8, 66, 119, 0.1);
    font-size: 18px;
  }
  .el-table th.el-table__cell.is-leaf {
    border-bottom: 1px solid #1d4d80;
  }
  .el-table th.el-table__cell {
    background: #084277;
  }
  .el-table--border {
    border: 1px solid #1d4d80;
  }
  .el-table--border .el-table__cell {
    border-right: 1px solid #1d4d80;
  }
  .el-table th.el-table__cell > .cell {
    color: #00aaff;
    font-size: 20px;
  }
  .el-table tr {
    background: rgba(8, 66, 119, 0.1);
  }
  .el-table {
    background: transparent;
    color: #ffffff;
  }
  .el-table--enable-row-hover .el-table__body tr:hover > td.el-table__cell {
    background: rgba(8, 66, 119, 0.5);
  }
  .el-table::before {
    height: 0;
  }
  .el-table--border::after {
    width: 0;
  }
  .el-pager li {
    color: #6599ca;
    background: transparent;
  }
  .el-pager li.active {
    color: #ffffff;
  }
  .el-pagination button:disabled {
    background-color: transparent;
  }
  .el-pagination .btn-next {
    background: center center no-repeat transparent;
    color: #ffffff;
  }
  .el-pagination .btn-prev {
    background: center center no-repeat transparent;
    color: #ffffff;
  }
}
.m-l-40 {
  margin-left: 40px;
}
</style>
<style>
.el-select-dropdown {
  background: #012b50;
  color: #ffffff;
  border: 1px solid #043661;
  box-shadow: inset 0px 0px 3px 0px #0180db;
}
.el-select-dropdown__item {
  color: #ffffff;
}
.el-select-dropdown__item.selected {
  background-color: #094888;
}
.el-select-dropdown__item.hover,
.el-select-dropdown__item:hover {
  background-color: #094888;
}
</style>
